package com.christina.listener;

import com.alibaba.fastjson.JSONObject;
import com.christina.config.RabbitMQConfig;
import com.christina.dto.NotificationMessage;
import com.christina.dto.TaskMessage;
import com.christina.service.domain.travel.TravelDomainService;
import com.christina.infrastructure.external.ExternalApiService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;

/**
 * 消息监听器
 * 
 * @author Christina
 */
@Slf4j
@Component
public class MessageListener {

    private final TravelDomainService travelDomainService;
    private final ExternalApiService externalApiService;

    public MessageListener(TravelDomainService travelDomainService, ExternalApiService externalApiService) {
        this.travelDomainService = travelDomainService;
        this.externalApiService = externalApiService;
    }

    /**
     * 监听聊天消息队列
     */
    @RabbitListener(queues = RabbitMQConfig.CHAT_QUEUE)
    public void handleChatMessage(JSONObject messageData, Message message, Channel channel) {
        try {
            log.info("收到聊天消息: {}", messageData);
            
            Long userId = (Long) messageData.get("userId");
            String messageContent = (String) messageData.get("message");
            
            // 这里可以添加聊天消息的异步处理逻辑
            // 例如：消息审核、敏感词过滤、消息统计等
            processChatMessage(userId, messageContent);
            
            // 手动确认消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            log.debug("聊天消息处理完成，用户ID: {}", userId);
            
        } catch (Exception e) {
            log.error("处理聊天消息失败", e);
            try {
                // 拒绝消息并重新入队
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            } catch (IOException ioException) {
                log.error("拒绝消息失败", ioException);
            }
        }
    }

    /**
     * 监听任务消息队列
     */
    @RabbitListener(queues = RabbitMQConfig.TASK_QUEUE)
    public void handleTaskMessage(Map<String, Object> messageData, Message message, Channel channel) {
        try {
            log.info("收到任务消息: {}", messageData);
            
            Long taskId = (Long) messageData.get("taskId");
            String taskType = (String) messageData.get("taskType");
            Object taskData = messageData.get("taskData");
            
            // 这里可以添加任务处理的异步逻辑
            // 例如：任务调度、状态更新、结果通知等
            processTaskMessage(taskId, taskType, taskData);
            
            // 手动确认消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            log.debug("任务消息处理完成，任务ID: {}", taskId);
            
        } catch (Exception e) {
            log.error("处理任务消息失败", e);
            try {
                // 拒绝消息并重新入队
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            } catch (IOException ioException) {
                log.error("拒绝消息失败", ioException);
            }
        }
    }

    /**
     * 监听通知消息队列
     */
    @RabbitListener(queues = RabbitMQConfig.NOTIFICATION_QUEUE)
    public void handleNotificationMessage(Map<String, Object> messageData, Message message, Channel channel) {
        try {
            log.info("收到通知消息: {}", messageData);
            
            Long userId = (Long) messageData.get("userId");
            String notificationType = (String) messageData.get("notificationType");
            String content = (String) messageData.get("content");
            
            // 这里可以添加通知处理的异步逻辑
            // 例如：推送通知、邮件发送、短信发送等
            processNotificationMessage(userId, notificationType, content);
            
            // 手动确认消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            log.debug("通知消息处理完成，用户ID: {}", userId);
            
        } catch (Exception e) {
            log.error("处理通知消息失败", e);
            try {
                // 拒绝消息并重新入队
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            } catch (IOException ioException) {
                log.error("拒绝消息失败", ioException);
            }
        }
    }

    /**
     * 处理聊天消息
     */
    private void processChatMessage(Long userId, String message) {
        // 实现聊天消息的具体处理逻辑
        log.info("处理用户{}的聊天消息: {}", userId, message);
        
        // 示例：消息长度统计
        if (message.length() > 1000) {
            log.warn("用户{}发送了长消息，长度: {}", userId, message.length());
        }
        
        // 可以在这里添加更多处理逻辑：
        // 1. 敏感词过滤
        // 2. 消息审核
        // 3. 用户行为分析
        // 4. 消息统计
    }

    /**
     * 处理任务消息
     */
    private void processTaskMessage(Long taskId, String taskType, Object taskData) {
        log.info("处理任务ID: {}, 类型: {}", taskId, taskType);
        
        try {
            switch (taskType) {
                case "TRAVEL_PLAN":
                    log.info("处理出行规划任务: {}", taskId);
                    processTravelPlanTask(taskData);
                    break;
                    
                case "TRAVEL_REMINDER":
                    log.info("处理出行提醒任务: {}", taskId);
                    processTravelReminderTask(taskData);
                    break;
                    
                case "AI_ANALYSIS":
                    log.info("处理AI分析任务: {}", taskId);
                    processAiAnalysisTask(taskData);
                    break;
                    
                case "EMAIL_SEND":
                    log.info("处理邮件发送任务: {}", taskId);
                    processEmailTask(taskData);
                    break;
                    
                case "DATA_BACKUP":
                    log.info("处理数据备份任务: {}", taskId);
                    processDataBackupTask(taskData);
                    break;
                    
                default:
                    log.warn("未知任务类型: {}", taskType);
            }
        } catch (Exception e) {
            log.error("处理任务失败，任务ID: {}, 类型: {}", taskId, taskType, e);
            // 这里可以实现重试逻辑或者发送失败通知
        }
    }
    
    /**
     * 处理出行规划任务
     */
    private void processTravelPlanTask(Object taskData) {
        log.info("执行出行规划任务");
        try {
            if (taskData instanceof TaskMessage) {
                TaskMessage task = (TaskMessage) taskData;
                @SuppressWarnings("unchecked")
                Map<String, Object> data = (Map<String, Object>) task.getTaskData();
                
                // 构建出行规划请求
                com.christina.service.domain.travel.model.TravelPlanRequest request = 
                    com.christina.service.domain.travel.model.TravelPlanRequest.builder()
                        .userId(task.getUserId())
                        .origin((String) data.get("origin"))
                        .destination((String) data.get("destination"))
                        .departureTime(java.time.LocalDateTime.now().plusDays(1))
                        .passengerCount(1)
                        .build();
                
                // 调用出行领域服务
                travelDomainService.createTravelPlan(request);
                log.info("出行规划任务处理完成");
            } else {
                log.warn("出行规划任务数据格式错误: {}", taskData.getClass());
            }
        } catch (Exception e) {
            log.error("处理出行规划任务失败", e);
        }
    }
    
    /**
     * 处理出行提醒任务
     */
    private void processTravelReminderTask(Object taskData) {
        log.info("执行出行提醒任务");
        try {
            if (taskData instanceof TaskMessage) {
                TaskMessage task = (TaskMessage) taskData;
                @SuppressWarnings("unchecked")
                Map<String, Object> data = (Map<String, Object>) task.getTaskData();
                Long travelPlanId = ((Number) data.get("travelPlanId")).longValue();
                
                // 生成提醒内容
                String reminderContent = "您的出行即将开始，请提前准备好相关证件和物品，祝您旅途愉快！";
                
                // 发送提醒通知
                NotificationMessage reminder = new NotificationMessage(
                    task.getUserId(),
                    NotificationMessage.NotificationType.REMINDER,
                    "出行提醒",
                    reminderContent
                );
                
                sendReminderNotification(reminder);
                log.info("出行提醒任务处理完成，规划ID: {}", travelPlanId);
            } else {
                log.warn("出行提醒任务数据格式错误: {}", taskData.getClass());
            }
        } catch (Exception e) {
            log.error("处理出行提醒任务失败", e);
        }
    }
    
    /**
     * 处理AI分析任务
     */
    private void processAiAnalysisTask(Object taskData) {
        log.info("执行AI分析任务");
        try {
            // 实现AI分析逻辑
            // 例如：用户行为分析、聊天内容分析、推荐算法等
            
            if (taskData instanceof TaskMessage) {
                TaskMessage task = (TaskMessage) taskData;
                log.info("分析用户{}的行为数据", task.getUserId());
                
                // 模拟AI分析处理
                Thread.sleep(1000);
                log.info("AI分析任务完成");
            }
        } catch (Exception e) {
            log.error("AI分析任务处理失败", e);
        }
    }
    
    /**
     * 处理邮件发送任务
     */
    private void processEmailTask(Object taskData) {
        log.info("执行邮件发送任务");
        try {
            if (taskData instanceof TaskMessage) {
                TaskMessage task = (TaskMessage) taskData;
                @SuppressWarnings("unchecked")
                Map<String, Object> data = (Map<String, Object>) task.getTaskData();
                
                String email = (String) data.get("email");
                String subject = (String) data.get("subject");
                String content = (String) data.get("content");
                
                // 调用外部API服务发送邮件
                boolean success = externalApiService.sendEmail(email, subject, content);
                
                if (success) {
                    log.info("邮件发送成功: {}", email);
                } else {
                    log.error("邮件发送失败: {}", email);
                }
            }
        } catch (Exception e) {
            log.error("邮件发送任务处理失败", e);
        }
    }
    
    /**
     * 处理数据备份任务
     */
    private void processDataBackupTask(Object taskData) {
        log.info("执行数据备份任务");
        try {
            // 实现数据备份逻辑
            // 例如：数据库备份、文件备份、日志归档等
            
            if (taskData instanceof TaskMessage) {
                TaskMessage task = (TaskMessage) taskData;
                @SuppressWarnings("unchecked")
                Map<String, Object> data = (Map<String, Object>) task.getTaskData();
                
                String backupType = (String) data.getOrDefault("backupType", "database");
                log.info("执行{}备份", backupType);
                
                // 模拟备份处理
                Thread.sleep(2000);
                log.info("数据备份任务完成");
            }
        } catch (Exception e) {
            log.error("数据备份任务处理失败", e);
        }
    }

    /**
     * 处理通知消息
     */
    private void processNotificationMessage(Long userId, String notificationType, Object content) {
        log.info("处理用户{}的{}通知", userId, notificationType);
        
        try {
            NotificationMessage notification = null;
            if (content instanceof NotificationMessage) {
                notification = (NotificationMessage) content;
            } else if (content instanceof String) {
                // 兼容旧格式
                notification = new NotificationMessage();
                notification.setUserId(userId);
                notification.setContent((String) content);
                notification.setType(NotificationMessage.NotificationType.valueOf(notificationType));
            }
            
            if (notification == null) {
                log.warn("通知消息格式错误: {}", content.getClass());
                return;
            }
            
            switch (notification.getType()) {
                case EMAIL:
                    sendEmailNotification(notification);
                    break;
                case SMS:
                    sendSmsNotification(notification);
                    break;
                case PUSH:
                    sendPushNotification(notification);
                    break;
                case SYSTEM:
                    sendSystemNotification(notification);
                    break;
                case REMINDER:
                    sendReminderNotification(notification);
                    break;
                default:
                    log.warn("未知通知类型: {}", notification.getType());
            }
        } catch (Exception e) {
            log.error("处理通知消息失败，用户ID: {}", userId, e);
        }
    }
    
    /**
     * 发送邮件通知
     */
    private void sendEmailNotification(NotificationMessage notification) {
        log.info("发送邮件通知给用户: {}, 标题: {}", notification.getUserId(), notification.getTitle());
        
        try {
            // 使用外部API服务发送邮件
            String email = "user" + notification.getUserId() + "@example.com"; // 实际应该从用户信息中获取
            boolean success = externalApiService.sendEmail(email, notification.getTitle(), notification.getContent());
            
            if (success) {
                log.info("邮件发送成功: {}", notification.getTitle());
            } else {
                log.error("邮件发送失败: {}", notification.getTitle());
            }
        } catch (Exception e) {
            log.error("邮件通知发送异常", e);
        }
    }
    
    /**
     * 发送短信通知
     */
    private void sendSmsNotification(NotificationMessage notification) {
        log.info("发送短信通知给用户: {}, 内容: {}", notification.getUserId(), notification.getContent());
        
        try {
            // 使用外部API服务发送短信
            String phone = "138****" + String.format("%04d", notification.getUserId() % 10000); // 模拟手机号
            boolean success = externalApiService.sendSms(phone, notification.getContent());
            
            if (success) {
                log.info("短信发送成功");
            } else {
                log.error("短信发送失败");
            }
        } catch (Exception e) {
            log.error("短信通知发送异常", e);
        }
    }
    
    /**
     * 发送推送通知
     */
    private void sendPushNotification(NotificationMessage notification) {
        log.info("发送推送通知给用户: {}, 标题: {}", notification.getUserId(), notification.getTitle());
        // 实现推送通知逻辑
        // 例如：使用极光推送、友盟推送等
        
        // 模拟推送发送
        try {
            Thread.sleep(200);
            log.info("推送通知发送成功");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    
    /**
     * 发送系统通知
     */
    private void sendSystemNotification(NotificationMessage notification) {
        log.info("发送系统通知给用户: {}, 内容: {}", notification.getUserId(), notification.getContent());
        // 实现系统内通知逻辑
        // 例如：保存到数据库、WebSocket推送等
        
        // 这里可以保存到数据库或通过WebSocket实时推送给用户
        log.info("系统通知已处理");
    }
    
    /**
     * 发送提醒通知
     */
    private void sendReminderNotification(NotificationMessage notification) {
        log.info("发送提醒通知给用户: {}, 内容: {}", notification.getUserId(), notification.getContent());
        // 实现提醒通知逻辑
        // 例如：设置闹钟、日历提醒等
        
        // 可以同时发送多种类型的提醒
        sendPushNotification(notification); // 推送提醒
        sendSystemNotification(notification); // 系统内提醒
        
        log.info("提醒通知已处理");
    }
}